#include"tcpServer.h"
#include"msg.h"
#include"logger.h"
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<string.h>
#include<iostream>
#include<unistd.h>


TcpServer::TcpServer(const IpAddressPort& ipAddressAndPort)
{
    m_mlfd=socket(AF_INET,SOCK_STREAM,0);
    if(m_mlfd==-1)
    {
        LOG_FATAL<<strerror(errno);
    }
    struct sockaddr_in ser;
    memset(&ser,0,sizeof(ser));
    ser.sin_family=AF_INET;
    //主机字节序-->网络字节序
    ser.sin_port=htons(ipAddressAndPort.GetPort());
    ser.sin_addr.s_addr=inet_addr(ipAddressAndPort.GetIpAddress().c_str());


    int res=bind(m_mlfd,(struct sockaddr*)&ser,sizeof(ser));
    if(-1==res)
    {
        LOG_FATAL<<strerror(errno);
    }
    if(-1==listen(m_mlfd,5))
    {
        LOG_FATAL<<strerror(errno);
    }
}
TcpServer::~TcpServer()
{
    if(-1==close(m_mlfd))
    {
       LOG_FATAL<<strerror(errno);
    }
}
int TcpServer::Accept()
{
    struct sockaddr_in cli;
    socklen_t len=sizeof(cli);
    int cfd=accept(m_mlfd,(struct sockaddr*)&cli,&len);
    if(-1==cfd)
    {
        LOG_ERROR<<strerror(errno);
        return -1;
    }
    else
    {
        char clientIpBuf[SMALL_BUF_LEN]={0};
        if(!inet_ntop(AF_INET,&cli.sin_addr,clientIpBuf,SMALL_BUF_LEN))
        {
            LOG_ERROR<<strerror(errno);
        }
        else
        {
            //网络字节序--->主机字节序
            std::string clientIp(clientIpBuf);
            unsigned short clientPort=ntohs(cli.sin_port);
            IpAddressPort IpAddressPort(clientIp,clientPort);
            LOG_ERROR<<IpAddressPort.ToString();
        }
    }
    return cfd;
}
int TcpServer::SendMsg(int cfd,const std::string&msg)
{
    int res=send(cfd,msg.c_str(),strlen(msg.c_str()),0);
    if(-1==res)
    {
        LOG_ERROR<<strerror(errno);
    }
    return res;
}
Msg TcpServer::RecvMsg(int cfd)
{
    char buf[LARGE_BUF_LEN]={0};
    int numberOfRecvByte=recv(cfd,buf,LARGE_BUF_LEN,0);
    if(-1==numberOfRecvByte)
    {
        LOG_ERROR<<strerror(errno);
    }
    //c风格
    //return Msg{.m_msg=buf,.m_numberOfRecvBytes=numberOfRecvBytes};
    return Msg{buf,numberOfRecvByte};
}
int TcpServer::GetSfd()const
{
    return m_mlfd;
}


int main()
{
    IpAddressPort ser("127.0.0.1",5000);
    TcpServer server(ser);
    while(1)
    {
        int cfd=server.Accept();
        if(-1==cfd)
        {
            continue;
        }
        while(1)
        {
           Msg m=server.RecvMsg(cfd);
           LOG_INFO<<m.ToString();
           server.SendMsg(cfd,"ok");
        }
    }
    return 0;
}